package com.nbcio.cd.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nbcio.cd.domain.CdFile;
import com.nbcio.cd.domain.CdFolder;
import com.nbcio.cd.domain.vo.CdFolderVo;
import com.nbcio.cd.mapper.CdFileMapper;
import com.nbcio.cd.mapper.CdFolderMapper;
import com.nbcio.cd.service.ICdFolderService;
import com.nbcio.cd.service.ICdPermissionService;
import com.nbcio.cd.utils.CdFileUtils;
import com.nbcio.cd.utils.CdPathUtils;
import com.nbcio.common.core.domain.R;
import com.nbcio.common.core.utils.MapstructUtils;
import com.nbcio.common.satoken.utils.LoginHelper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 云网盘文件夹Service业务层处理
 *
 * @author nbacheng
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class CdFolderServiceImpl extends ServiceImpl<CdFolderMapper, CdFolder> implements ICdFolderService {

    private final CdFolderMapper cdFolderMapper;
    private final CdFileMapper cdFileMapper;
    private final ICdPermissionService cdPermissionService;

    /**
     * 创建文件夹
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CdFolderVo createFolder(String folderName, Long parentId, Long projectId) {
        try {
            // 验证文件夹名称
            if (StrUtil.isBlank(folderName)) {
                throw new RuntimeException("文件夹名称不能为空");
            }
            
            // 验证父文件夹
            CdFolder parentFolder = validateParentFolder(parentId);
            
            // 检查同级目录下是否有重名文件夹
            LambdaQueryWrapper<CdFolder> wrapper = new LambdaQueryWrapper<CdFolder>();
            wrapper.eq(CdFolder::getParentId, parentId)
                   .eq(CdFolder::getFolderName, folderName);
            
            if (cdFolderMapper.selectCount(wrapper) > 0) {
                throw new RuntimeException("同级目录下已存在同名文件夹");
            }
            
            // 构建文件夹路径
            String folderPath = buildFolderPath(parentFolder, folderName);
            
            // 创建文件夹
            CdFolder cdFolder = new CdFolder();
            cdFolder.setFolderName(folderName);
            cdFolder.setParentId(parentId);
            cdFolder.setFolderPath(folderPath);
            cdFolder.setFolderType(projectId != null ? "project" : "personal");
            cdFolder.setOwnerId(LoginHelper.getUserId());
            cdFolder.setProjectId(projectId);
            cdFolder.setFolderSize(0L);
            cdFolder.setFileCount(0);
            cdFolder.setFolderCount(0);
            cdFolder.setIsShared(false);
            cdFolder.setAccessLevel("private");
            cdFolder.setStatus("0");
            
            cdFolderMapper.insert(cdFolder);
            
            // 更新父文件夹统计
            updateParentFolderStats(parentId);
            
            return buildFolderVo(cdFolder);
            
        } catch (Exception e) {
            log.error("创建文件夹失败: {}", e.getMessage(), e);
            throw new RuntimeException("创建文件夹失败: " + e.getMessage());
        }
    }

    /**
     * 重命名文件夹
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean renameFolder(Long folderId, String newName) {
        try {
            // 获取文件夹信息
            CdFolder cdFolder = cdFolderMapper.selectById(folderId);
            if (cdFolder == null) {
                throw new RuntimeException("文件夹不存在");
            }
            
            // 检查权限
            if (!checkFolderPermission(folderId, "write")) {
                throw new RuntimeException("无权限重命名此文件夹");
            }
            
            // 验证新名称
            if (StrUtil.isBlank(newName)) {
                throw new RuntimeException("文件夹名称不能为空");
            }
            
            // 检查同级目录下是否有重名文件夹
            LambdaQueryWrapper<CdFolder> wrapper = new LambdaQueryWrapper<CdFolder>();
            wrapper.eq(CdFolder::getParentId, cdFolder.getParentId())
                   .eq(CdFolder::getFolderName, newName)
                   .ne(CdFolder::getFolderId, folderId);
            
            if (cdFolderMapper.selectCount(wrapper) > 0) {
                throw new RuntimeException("同级目录下已存在同名文件夹");
            }
            
            // 更新文件夹信息
            cdFolder.setFolderName(newName);
            cdFolder.setFolderPath(buildFolderPath(cdFolderMapper.selectById(cdFolder.getParentId()), newName));
            cdFolderMapper.updateById(cdFolder);
            
            // 更新子文件夹路径
            updateSubFolderPaths(folderId, cdFolder.getFolderPath());
            
            return true;
            
        } catch (Exception e) {
            log.error("重命名文件夹失败: {}", e.getMessage(), e);
            throw new RuntimeException("重命名文件夹失败: " + e.getMessage());
        }
    }

    /**
     * 移动文件夹
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean moveFolder(Long folderId, Long targetParentId) {
        try {
            // 获取文件夹信息
            CdFolder cdFolder = cdFolderMapper.selectById(folderId);
            if (cdFolder == null) {
                throw new RuntimeException("文件夹不存在");
            }
            
            // 检查权限
            if (!checkFolderPermission(folderId, "write")) {
                throw new RuntimeException("无权限移动此文件夹");
            }
            
            // 验证目标父文件夹
            CdFolder targetParentFolder = validateParentFolder(targetParentId);
            
            // 检查是否移动到自己的子文件夹中
            if (isSubFolder(folderId, targetParentId)) {
                throw new RuntimeException("不能将文件夹移动到自己的子文件夹中");
            }
            
            // 检查目标文件夹下是否有重名文件夹
            LambdaQueryWrapper<CdFolder> wrapper = new LambdaQueryWrapper<CdFolder>();
            wrapper.eq(CdFolder::getParentId, targetParentId)
                   .eq(CdFolder::getFolderName, cdFolder.getFolderName())
                   .ne(CdFolder::getFolderId, folderId);
            
            if (cdFolderMapper.selectCount(wrapper) > 0) {
                throw new RuntimeException("目标文件夹下已存在同名文件夹");
            }
            
            // 更新文件夹信息
            cdFolder.setParentId(targetParentId);
            cdFolder.setFolderPath(buildFolderPath(targetParentFolder, cdFolder.getFolderName()));
            cdFolderMapper.updateById(cdFolder);
            
            // 更新子文件夹路径
            updateSubFolderPaths(folderId, cdFolder.getFolderPath());
            
            // 更新文件夹统计
            updateParentFolderStats(cdFolder.getParentId());
            updateParentFolderStats(targetParentId);
            
            return true;
            
        } catch (Exception e) {
            log.error("移动文件夹失败: {}", e.getMessage(), e);
            throw new RuntimeException("移动文件夹失败: " + e.getMessage());
        }
    }

    /**
     * 复制文件夹
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean copyFolder(Long folderId, Long targetParentId) {
        try {
            // 获取文件夹信息
            CdFolder cdFolder = cdFolderMapper.selectById(folderId);
            if (cdFolder == null) {
                throw new RuntimeException("文件夹不存在");
            }
            
            // 检查权限
            if (!checkFolderPermission(folderId, "read")) {
                throw new RuntimeException("无权限复制此文件夹");
            }
            
            // 验证目标父文件夹
            CdFolder targetParentFolder = validateParentFolder(targetParentId);
            
            // 检查目标文件夹下是否有重名文件夹
            LambdaQueryWrapper<CdFolder> wrapper = new LambdaQueryWrapper<CdFolder>();
            wrapper.eq(CdFolder::getParentId, targetParentId)
                   .eq(CdFolder::getFolderName, cdFolder.getFolderName());
            
            if (cdFolderMapper.selectCount(wrapper) > 0) {
                throw new RuntimeException("目标文件夹下已存在同名文件夹");
            }
            
            // 复制文件夹及其子文件夹
            copyFolderRecursive(cdFolder, targetParentId, targetParentFolder);
            
            // 更新目标文件夹统计
            updateParentFolderStats(targetParentId);
            
            return true;
            
        } catch (Exception e) {
            log.error("复制文件夹失败: {}", e.getMessage(), e);
            throw new RuntimeException("复制文件夹失败: " + e.getMessage());
        }
    }

    /**
     * 删除文件夹
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteFolders(List<Long> folderIds) {
        try {
            if (ObjectUtil.isEmpty(folderIds)) {
                return true;
            }
            
            // 检查权限并删除文件夹
            for (Long folderId : folderIds) {
                // 直接进行删除操作，deleteFolderRecursive内部会处理
                try {
                    // 删除文件夹及其子文件夹（软删除）
                    deleteFolderRecursive(folderId);
                    log.info("文件夹 {} 删除成功", folderId);
                } catch (Exception e) {
                    log.error("删除文件夹 {} 失败: {}", folderId, e.getMessage(), e);
                    // 继续删除其他文件夹，不中断整个过程
                }
            }
            
            return true;
            
        } catch (Exception e) {
            log.error("删除文件夹失败: {}", e.getMessage(), e);
            throw new RuntimeException("删除文件夹失败: " + e.getMessage());
        }
    }

    /**
     * 获取文件夹树
     */
    @Override
    public List<CdFolderVo> getFolderTree(Long userId, Long projectId) {
        try {
            log.info("获取文件夹树 - userId: {}, projectId: {}", userId, projectId);
            
            // 获取当前登录用户ID
            Long currentUserId = LoginHelper.getUserId();
            
            // 查询所有文件夹（不按ownerId过滤），然后通过权限过滤
            // 传入null作为userId，这样SQL不会按owner_id过滤
            List<CdFolder> folders = cdFolderMapper.selectFolderTree(null, projectId);
            log.info("查询到的文件夹数量: {}", folders.size());
            
            for (CdFolder folder : folders) {
                log.info("文件夹: id={}, name={}, parentId={}, ownerId={}", 
                    folder.getFolderId(), folder.getFolderName(), folder.getParentId(), folder.getOwnerId());
            }
            
            // 过滤有权限的文件夹（owner或有读取权限）
            List<CdFolder> authorizedFolders = folders.stream()
                    .filter(folder -> {
                        // 所有者拥有所有权限
                        if (folder.getOwnerId().equals(currentUserId)) {
                            return true;
                        }
                        // 检查是否有读取权限
                        return cdPermissionService.checkUserPermission(currentUserId, "folder", folder.getFolderId(), "read");
                    })
                    .collect(Collectors.toList());
            
            log.info("过滤后有权限的文件夹数量: {}", authorizedFolders.size());
            
            // 构建树结构
            List<CdFolderVo> result = buildFolderTree(authorizedFolders, 0L);
            log.info("构建的树形结构数量: {}", result.size());
            
            return result;
            
        } catch (Exception e) {
            log.error("获取文件夹树失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取文件夹树失败: " + e.getMessage());
        }
    }

    /**
     * 查询文件夹列表
     */
    @Override
    public R<List<CdFolderVo>> queryFolderList(Long parentId, String folderName, String folderType, CdFolderVo pageQuery) {
        try {
            // 检查父文件夹是否存在
            CdFolder parentFolder = checkParentFolder(parentId);
            
            // 如果父文件夹不存在且不是根文件夹，返回空列表
            if (parentFolder == null && parentId != null && parentId != 0L) {
                return R.ok(new ArrayList<>());
            }
            
            // 获取当前用户ID
            Long currentUserId = LoginHelper.getUserId();
            
            // 如果父文件夹不是根目录，检查是否有权限访问父文件夹
            if (parentId != null && parentId != 0L && parentFolder != null) {
                // 如果不是父文件夹的所有者，检查是否有读取权限
                if (!parentFolder.getOwnerId().equals(currentUserId)) {
                    boolean hasPermission = cdPermissionService.checkUserPermission(currentUserId, "folder", parentId, "read");
                    if (!hasPermission) {
                        // 无权限访问父文件夹，返回空列表
                        return R.ok(new ArrayList<>());
                    }
                }
            }
            
            // 构建查询条件
            LambdaQueryWrapper<CdFolder> wrapper = new LambdaQueryWrapper<CdFolder>();
            wrapper.eq(CdFolder::getParentId, parentId);
            
            if (StrUtil.isNotBlank(folderName)) {
                wrapper.like(CdFolder::getFolderName, folderName);
            }
            
            if (StrUtil.isNotBlank(folderType)) {
                wrapper.eq(CdFolder::getFolderType, folderType);
            }
            
            wrapper.orderByDesc(CdFolder::getCreateTime);
            
            // 分页查询
            List<CdFolder> list = cdFolderMapper.selectList(wrapper);
            
            // 过滤有权限的文件夹（owner或有读取权限）
            List<CdFolder> authorizedList = list.stream()
                    .filter(folder -> {
                        // 所有者拥有所有权限
                        if (folder.getOwnerId().equals(currentUserId)) {
                            return true;
                        }
                        // 检查是否有读取权限
                        return cdPermissionService.checkUserPermission(currentUserId, "folder", folder.getFolderId(), "read");
                    })
                    .collect(Collectors.toList());
            
            // 转换为VO
            List<CdFolderVo> voList = authorizedList.stream()
                    .map(this::buildFolderVo)
                    .collect(Collectors.toList());
            
            return R.ok(voList);
            
        } catch (Exception e) {
            log.error("查询文件夹列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("查询文件夹列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取文件夹详情
     */
    @Override
    public CdFolderVo getFolderInfo(Long folderId) {
        try {
            CdFolder cdFolder = cdFolderMapper.selectById(folderId);
            if (cdFolder == null) {
                throw new RuntimeException("文件夹不存在");
            }
            
            // 检查权限
            if (!checkFolderPermission(folderId, "read")) {
                throw new RuntimeException("无权限查看此文件夹");
            }
            
            return buildFolderVo(cdFolder);
            
        } catch (Exception e) {
            log.error("获取文件夹详情失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取文件夹详情失败: " + e.getMessage());
        }
    }

    /**
     * 检查文件夹权限
     */
    @Override
    public Boolean checkFolderPermission(Long folderId, String permissionType) {
        try {
            Long userId = LoginHelper.getUserId();
            CdFolder cdFolder = cdFolderMapper.selectById(folderId);
            
            if (cdFolder == null) {
                return false;
            }
            
            // 文件夹所有者拥有所有权限
            if (cdFolder.getOwnerId().equals(userId)) {
                return true;
            }
            
            // TODO: 实现更复杂的权限检查逻辑
            // 这里可以根据权限表进行更详细的权限验证
            
            return false;
            
        } catch (Exception e) {
            log.error("检查文件夹权限失败: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 更新文件夹统计信息
     */
    @Override
    public void updateFolderStats(Long folderId) {
        try {
            // 统计文件数量和大小
            LambdaQueryWrapper<CdFolder> wrapper = new LambdaQueryWrapper<CdFolder>();
            wrapper.eq(CdFolder::getParentId, folderId);
            
            List<CdFolder> subFolders = cdFolderMapper.selectList(wrapper);
            int folderCount = subFolders.size();
            
            // 更新文件夹统计
            cdFolderMapper.updateFolderCount(folderId, folderCount);
            
        } catch (Exception e) {
            log.error("更新文件夹统计失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 获取用户根文件夹
     */
    @Override
    public CdFolder getUserRootFolder(Long userId) {
        try {
            LambdaQueryWrapper<CdFolder> wrapper = new LambdaQueryWrapper<CdFolder>();
            wrapper.eq(CdFolder::getOwnerId, userId)
                   .eq(CdFolder::getParentId, 0L)
                   .eq(CdFolder::getFolderType, "personal");
            
            CdFolder rootFolder = cdFolderMapper.selectOne(wrapper);
            
            if (rootFolder == null) {
                // 创建用户根文件夹
                rootFolder = new CdFolder();
                rootFolder.setFolderName("我的文件");
                rootFolder.setParentId(0L);
                rootFolder.setFolderPath("/");
                rootFolder.setFolderType("personal");
                rootFolder.setOwnerId(userId);
                rootFolder.setFolderSize(0L);
                rootFolder.setFileCount(0);
                rootFolder.setFolderCount(0);
                rootFolder.setIsShared(false);
                rootFolder.setAccessLevel("private");
                rootFolder.setStatus("0");
                
                cdFolderMapper.insert(rootFolder);
            }
            
            return rootFolder;
            
        } catch (Exception e) {
            log.error("获取用户根文件夹失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取用户根文件夹失败: " + e.getMessage());
        }
    }

    /**
     * 获取项目根文件夹
     */
    @Override
    public CdFolder getProjectRootFolder(Long projectId) {
        try {
            LambdaQueryWrapper<CdFolder> wrapper = new LambdaQueryWrapper<CdFolder>();
            wrapper.eq(CdFolder::getProjectId, projectId)
                   .eq(CdFolder::getParentId, 0L)
                   .eq(CdFolder::getFolderType, "project");
            
            CdFolder rootFolder = cdFolderMapper.selectOne(wrapper);
            
            if (rootFolder == null) {
                // 创建项目根文件夹
                rootFolder = new CdFolder();
                rootFolder.setFolderName("项目文件");
                rootFolder.setParentId(0L);
                rootFolder.setFolderPath("/");
                rootFolder.setFolderType("project");
                rootFolder.setProjectId(projectId);
                rootFolder.setFolderSize(0L);
                rootFolder.setFileCount(0);
                rootFolder.setFolderCount(0);
                rootFolder.setIsShared(false);
                rootFolder.setAccessLevel("private");
                rootFolder.setStatus("0");
                
                cdFolderMapper.insert(rootFolder);
            }
            
            return rootFolder;
            
        } catch (Exception e) {
            log.error("获取项目根文件夹失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取项目根文件夹失败: " + e.getMessage());
        }
    }

    // ==================== 私有方法 ====================

    /**
     * 验证父文件夹
     */
    private CdFolder validateParentFolder(Long parentId) {
        if (parentId == null || parentId == 0L) {
            return null; // 根文件夹
        }
        
        CdFolder parentFolder = cdFolderMapper.selectById(parentId);
        if (parentFolder == null) {
            throw new RuntimeException("父文件夹不存在");
        }
        
        return parentFolder;
    }

    /**
     * 检查父文件夹是否存在（不抛出异常）
     */
    private CdFolder checkParentFolder(Long parentId) {
        if (parentId == null || parentId == 0L) {
            return null; // 根文件夹
        }
        
        return cdFolderMapper.selectById(parentId);
    }

    /**
     * 构建文件夹路径
     */
    private String buildFolderPath(CdFolder parentFolder, String folderName) {
        if (parentFolder == null) {
            return "/" + folderName;
        }
        
        String parentPath = parentFolder.getFolderPath();
        if ("/".equals(parentPath)) {
            return "/" + folderName;
        } else {
            return parentPath + "/" + folderName;
        }
    }

    /**
     * 检查是否为子文件夹
     */
    private boolean isSubFolder(Long folderId, Long targetParentId) {
        if (folderId.equals(targetParentId)) {
            return true;
        }
        
        CdFolder folder = cdFolderMapper.selectById(targetParentId);
        while (folder != null && folder.getParentId() != 0L) {
            if (folder.getParentId().equals(folderId)) {
                return true;
            }
            folder = cdFolderMapper.selectById(folder.getParentId());
        }
        
        return false;
    }

    /**
     * 检查是否为根文件夹
     */
    private boolean isRootFolder(Long folderId) {
        CdFolder folder = cdFolderMapper.selectById(folderId);
        if (folder == null) {
            return false;
        }
        
        // 根文件夹的条件：
        // 1. parentId = 0
        // 2. 文件夹名称为"我的文件"
        // 3. 文件夹类型为"personal"
        return folder.getParentId() == 0L 
            && "我的文件".equals(folder.getFolderName())
            && "personal".equals(folder.getFolderType());
    }

    /**
     * 更新子文件夹路径
     */
    private void updateSubFolderPaths(Long folderId, String newPath) {
        LambdaQueryWrapper<CdFolder> wrapper = new LambdaQueryWrapper<CdFolder>();
        wrapper.eq(CdFolder::getParentId, folderId);
        
        List<CdFolder> subFolders = cdFolderMapper.selectList(wrapper);
        for (CdFolder subFolder : subFolders) {
            subFolder.setFolderPath(newPath + "/" + subFolder.getFolderName());
            cdFolderMapper.updateById(subFolder);
            
            // 递归更新子文件夹
            updateSubFolderPaths(subFolder.getFolderId(), subFolder.getFolderPath());
        }
    }

    /**
     * 更新父文件夹统计
     */
    private void updateParentFolderStats(Long parentId) {
        if (parentId == null || parentId == 0L) {
            return;
        }
        
        LambdaQueryWrapper<CdFolder> wrapper = new LambdaQueryWrapper<CdFolder>();
        wrapper.eq(CdFolder::getParentId, parentId);
        
        List<CdFolder> subFolders = cdFolderMapper.selectList(wrapper);
        int folderCount = subFolders.size();
        
        cdFolderMapper.updateFolderCount(parentId, folderCount);
    }

    /**
     * 递归复制文件夹
     */
    private void copyFolderRecursive(CdFolder sourceFolder, Long targetParentId, CdFolder targetParentFolder) {
        // 创建新文件夹
        CdFolder newFolder = new CdFolder();
        BeanUtil.copyProperties(sourceFolder, newFolder);
        newFolder.setFolderId(null);
        newFolder.setParentId(targetParentId);
        newFolder.setFolderPath(buildFolderPath(targetParentFolder, sourceFolder.getFolderName()));
        newFolder.setFolderSize(0L);
        newFolder.setFileCount(0);
        newFolder.setFolderCount(0);
        newFolder.setIsShared(false);
        newFolder.setShareCode(null);
        newFolder.setShareExpireTime(null);
        newFolder.setCreateTime(new Date());
        newFolder.setUpdateTime(new Date());
        
        cdFolderMapper.insert(newFolder);
        
        // 复制子文件夹
        LambdaQueryWrapper<CdFolder> wrapper = new LambdaQueryWrapper<CdFolder>();
        wrapper.eq(CdFolder::getParentId, sourceFolder.getFolderId());
        
        List<CdFolder> subFolders = cdFolderMapper.selectList(wrapper);
        for (CdFolder subFolder : subFolders) {
            copyFolderRecursive(subFolder, newFolder.getFolderId(), newFolder);
        }
    }

    /**
     * 递归删除文件夹
     */
    private void deleteFolderRecursive(Long folderId) {
        log.info("开始删除文件夹: {}", folderId);
        
        // 直接查询所有文件夹，包括已删除的
        LambdaQueryWrapper<CdFolder> queryWrapper = new LambdaQueryWrapper<CdFolder>();
        queryWrapper.eq(CdFolder::getFolderId, folderId);
        queryWrapper.last("LIMIT 1");
        
        CdFolder cdFolder = cdFolderMapper.selectOne(queryWrapper);
        if (cdFolder == null) {
            log.warn("文件夹不存在: {}", folderId);
            return;
        }
        
        // 如果已经删除，跳过
        if ("2".equals(cdFolder.getDelFlag())) {
            log.info("文件夹已删除: {}", folderId);
            return;
        }
        
        log.info("找到文件夹: {}, 文件夹名: {}", folderId, cdFolder.getFolderName());
        
        // 检查权限
        if (!checkFolderPermission(folderId, "delete")) {
            log.error("无权限删除文件夹: {}", cdFolder.getFolderName());
            throw new RuntimeException("无权限删除文件夹: " + cdFolder.getFolderName());
        }
        
        // 检查是否为根文件夹
        if (isRootFolder(folderId)) {
            log.error("不能删除根文件夹: {}", folderId);
            throw new RuntimeException("不能删除根文件夹");
        }
        
        // 保存父文件夹ID，用于后续更新统计
        Long parentId = cdFolder.getParentId();
        
        // 删除子文件夹
        LambdaQueryWrapper<CdFolder> wrapper = new LambdaQueryWrapper<CdFolder>();
        wrapper.eq(CdFolder::getParentId, folderId);
        
        List<CdFolder> subFolders = cdFolderMapper.selectList(wrapper);
        log.info("文件夹 {} 下有 {} 个子文件夹", folderId, subFolders.size());
        for (CdFolder subFolder : subFolders) {
            deleteFolderRecursive(subFolder.getFolderId());
        }
        
        // 删除文件夹下的所有文件
        log.info("开始删除文件夹 {} 下的文件", folderId);
        deleteFilesInFolder(folderId);
        
        // 删除当前文件夹（逻辑删除 - MyBatis-Plus会自动处理delFlag）
        log.info("开始删除文件夹: {}, ID: {}", cdFolder.getFolderName(), folderId);
        cdFolderMapper.deleteById(folderId);
        log.info("文件夹 {} 删除完成", folderId);
        
        // 更新父文件夹统计
        updateParentFolderStats(parentId);
    }
    
    /**
     * 删除文件夹下的所有文件
     */
    private void deleteFilesInFolder(Long folderId) {
        // 查询文件夹下的所有文件（包括已删除的，因为我们也要删除它们）
        LambdaQueryWrapper<CdFile> fileWrapper = new LambdaQueryWrapper<CdFile>();
        fileWrapper.eq(CdFile::getFolderId, folderId);
        
        List<CdFile> files = cdFileMapper.selectList(fileWrapper);
        if (files != null && !files.isEmpty()) {
            // 软删除文件记录 - MyBatis-Plus会自动处理delFlag
            for (CdFile file : files) {
                cdFileMapper.deleteById(file.getFileId());
            }
            log.info("删除文件夹 {} 下的 {} 个文件", folderId, files.size());
        }
    }

    /**
     * 构建文件夹树
     */
    private List<CdFolderVo> buildFolderTree(List<CdFolder> folders, Long parentId) {
        log.info("buildFolderTree - parentId: {}, folders数量: {}", parentId, folders.size());
        
        List<CdFolderVo> tree = new ArrayList<>();
        
        for (CdFolder folder : folders) {
            log.info("检查文件夹: id={}, name={}, parentId={}, 目标parentId={}, 匹配: {}", 
                folder.getFolderId(), folder.getFolderName(), folder.getParentId(), parentId, 
                folder.getParentId().equals(parentId));
            
            if (folder.getParentId().equals(parentId)) {
                CdFolderVo vo = buildFolderVo(folder);
                vo.setChildren(buildFolderTree(folders, folder.getFolderId()));
                vo.setExpanded(false);
                vo.setLeaf(vo.getChildren().isEmpty());
                tree.add(vo);
                log.info("添加文件夹到树: {}", folder.getFolderName());
            }
        }
        
        log.info("buildFolderTree - parentId: {}, 找到子文件夹数量: {}", parentId, tree.size());
        return tree;
    }

    /**
     * 构建文件夹VO
     */
    private CdFolderVo buildFolderVo(CdFolder cdFolder) {
        CdFolderVo vo = new CdFolderVo();
        
        // 手动复制属性
        vo.setFolderId(cdFolder.getFolderId());
        vo.setFolderName(cdFolder.getFolderName());
        vo.setParentId(cdFolder.getParentId());
        vo.setFolderPath(cdFolder.getFolderPath());
        vo.setFolderType(cdFolder.getFolderType());
        vo.setOwnerId(cdFolder.getOwnerId());
        vo.setProjectId(cdFolder.getProjectId());
        vo.setFolderSize(cdFolder.getFolderSize());
        vo.setFileCount(cdFolder.getFileCount());
        vo.setFolderCount(cdFolder.getFolderCount());
        vo.setIsShared(cdFolder.getIsShared());
        vo.setAccessLevel(cdFolder.getAccessLevel());
        vo.setStatus(cdFolder.getStatus());
        vo.setCreateBy(cdFolder.getCreateBy());
        vo.setCreateTime(cdFolder.getCreateTime());
        vo.setUpdateBy(cdFolder.getUpdateBy());
        vo.setUpdateTime(cdFolder.getUpdateTime());
        vo.setDelFlag(cdFolder.getDelFlag());
        vo.setCreateDept(cdFolder.getCreateDept());
        
        // 设置格式化的大小
        vo.setFolderSizeFormatted(CdFileUtils.formatFileSize(cdFolder.getFolderSize()));
        
        // 如果folderPath为空，则递归计算路径
        if (StrUtil.isBlank(vo.getFolderPath())) {
            String computedPath = getFolderPath(cdFolder.getFolderId());
            vo.setFolderPath(computedPath);
        }
        
        // 设置是否为当前用户拥有
        Long currentUserId = LoginHelper.getUserId();
        vo.setIsOwned(cdFolder.getOwnerId().equals(currentUserId));
        
        return vo;
    }
    
    /**
     * 获取文件夹路径（递归获取父文件夹名称，用/分隔）
     */
    private String getFolderPath(Long folderId) {
        if (folderId == null || folderId == 0L) {
            return "/";
        }
        
        List<String> folderNames = new ArrayList<>();
        Long currentFolderId = folderId;
        
        // 递归查找父文件夹
        while (currentFolderId != null && currentFolderId != 0L) {
            CdFolder folder = cdFolderMapper.selectById(currentFolderId);
            if (folder == null) {
                break;
            }
            folderNames.add(0, folder.getFolderName()); // 添加到列表开头
            currentFolderId = folder.getParentId();
        }
        
        // 拼接路径
        if (folderNames.isEmpty()) {
            return "/";
        }
        
        return "/" + String.join("/", folderNames);
    }

    /**
     * 根据ID删除文件夹（递归删除）
     */
    @Override
    public Boolean deleteByFolderId(Long folderId) {
        deleteFolderRecursive(folderId);
        return true;
    }
}
